Komplexní průvodce slučováním a spojováním DataFrame v Python Pandas. Pokrývá inner, outer, left a right joins s příklady pro globální analýzu dat.
Slučování v Python Pandas: Zvládnutí strategií spojování DataFrame pro analýzu dat
Manipulace s daty je klíčovým aspektem analýzy dat a knihovna Pandas v Pythonu poskytuje pro tento účel výkonné nástroje. Mezi tyto nástroje patří slučování a spojování datových rámců (DataFrames), což jsou základní operace pro kombinování datových sad na základě společných sloupců nebo indexů. Tento komplexní průvodce zkoumá různé strategie spojování DataFrames v Pandas a vybaví vás znalostmi pro efektivní kombinování a analýzu dat z různých zdrojů.
Pochopení slučování a spojování DataFrames
Slučování a spojování DataFrames zahrnuje kombinování dvou nebo více DataFrames do jednoho DataFrame na základě sdíleného sloupce nebo indexu. Hlavní rozdíl mezi `merge` a `join` spočívá v tom, že `merge` je funkce knihovny Pandas a obvykle spojuje DataFrames podle sloupců, zatímco `join` je metoda DataFrame, která spojuje DataFrames primárně podle indexů, i když ji lze použít i se sloupci.
Klíčové pojmy
- DataFrames: Dvourozměrné označené datové struktury se sloupci potenciálně různých typů.
- Společné sloupce/indexy: Sloupce nebo indexy, které sdílejí stejný název a datový typ napříč DataFrames a slouží jako základ pro slučování/spojování.
- Typy spojení: Různé strategie pro zpracování neshodných řádků během procesu slučování/spojování, včetně inner, outer, left a right joins.
Slučování DataFrames pomocí `pd.merge()`
Funkce `pd.merge()` je primárním nástrojem pro slučování DataFrames na základě sloupců. Nabízí flexibilní způsob kombinování dat na základě jednoho nebo více společných sloupců.
Syntaxe
pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None, left_index=False, right_index=False, sort=False, suffixes=('_x', '_y'), copy=True, indicator=False, validate=None)
Parametry
- left: Levý DataFrame ke sloučení.
- right: Pravý DataFrame ke sloučení.
- how: Typ prováděného sloučení ('inner', 'outer', 'left', 'right'). Výchozí hodnota je 'inner'.
- on: Název sloupce(ů) pro spojení. Tyto sloupce musí být nalezeny v obou DataFrames.
- left_on: Název sloupce(ů) v levém DataFrame, které se použijí jako spojovací klíče.
- right_on: Název sloupce(ů) v pravém DataFrame, které se použijí jako spojovací klíče.
- left_index: Pokud True, použije index z levého DataFrame jako spojovací klíč(e).
- right_index: Pokud True, použije index z pravého DataFrame jako spojovací klíč(e).
- sort: Seřadí výsledný DataFrame lexikograficky podle spojovacích klíčů. Výchozí hodnota je False.
- suffixes: N-tice (tuple) řetězcových přípon, které se aplikují na překrývající se názvy sloupců. Výchozí hodnota je ('_x', '_y').
- copy: Pokud False, vyhne se kopírování dat do nového DataFrame, kde je to možné. Výchozí hodnota je True.
- indicator: Pokud True, přidá sloupec s názvem '_merge' indikující zdroj každého řádku.
- validate: Kontroluje, zda sloučení je zadaného typu. "one_to_one", "one_to_many", "many_to_one", "many_to_many".
Vysvětlení typů spojení
Parametr `how` ve funkci `pd.merge()` určuje typ provedeného spojení. Různé typy spojení zpracovávají neshodné řádky různými způsoby.
Inner Join (Vnitřní spojení)
Inner join vrací pouze ty řádky, které mají odpovídající hodnoty v obou DataFrames na základě spojovacích klíčů. Řádky s neshodnými hodnotami jsou z výsledku vyloučeny.
Příklad:
Uvažujme dva DataFrames:
import pandas as pd
# DataFrame 1: Customer Orders
df_orders = pd.DataFrame({
'order_id': [1, 2, 3, 4, 5],
'customer_id': [101, 102, 103, 104, 105],
'product_id': [1, 2, 1, 3, 2],
'quantity': [2, 1, 3, 1, 2]
})
# DataFrame 2: Customer Information
df_customers = pd.DataFrame({
'customer_id': [101, 102, 103, 106],
'customer_name': ['Alice', 'Bob', 'Charlie', 'David'],
'country': ['USA', 'Canada', 'UK', 'Australia']
})
# Inner Join
df_inner = pd.merge(df_orders, df_customers, on='customer_id', how='inner')
print(df_inner)
Výstup:
order_id customer_id product_id quantity customer_name country
0 1 101 1 2 Alice USA
1 2 102 2 1 Bob Canada
2 3 103 1 3 Charlie UK
V tomto příkladu inner join kombinuje DataFrames `df_orders` a `df_customers` na základě sloupce `customer_id`. Do výsledku jsou zahrnuti pouze zákazníci, kteří zadali objednávky. Zákazník 'David' (customer_id 106) je vyloučen, protože nemá žádné objednávky.
Outer Join (Plné vnější spojení)
Outer join vrací všechny řádky z obou DataFrames, včetně neshodných řádků. Pokud řádek nemá shodu v druhém DataFrame, odpovídající sloupce budou obsahovat hodnoty `NaN` (Not a Number).
Příklad:
# Outer Join
df_outer = pd.merge(df_orders, df_customers, on='customer_id', how='outer')
print(df_outer)
Výstup:
order_id customer_id product_id quantity customer_name country
0 1.0 101 1.0 2.0 Alice USA
1 2.0 102 2.0 1.0 Bob Canada
2 3.0 103 1.0 3.0 Charlie UK
3 4.0 104 3.0 1.0 NaN NaN
4 5.0 105 2.0 2.0 NaN NaN
5 NaN 106 NaN NaN David Australia
Outer join zahrnuje všechny zákazníky a všechny objednávky. Zákazníci 104 a 105 mají objednávky, ale nemají zákaznické informace, a zákazník 106 má zákaznické informace, ale nemá objednávky. Chybějící hodnoty jsou reprezentovány jako `NaN`.
Left Join (Levé spojení)
Left join vrací všechny řádky z levého DataFrame a odpovídající řádky z pravého DataFrame. Pokud řádek v levém DataFrame nemá shodu v pravém DataFrame, odpovídající sloupce z pravého DataFrame budou obsahovat hodnoty `NaN`.
Příklad:
# Left Join
df_left = pd.merge(df_orders, df_customers, on='customer_id', how='left')
print(df_left)
Výstup:
order_id customer_id product_id quantity customer_name country
0 1 101 1 2 Alice USA
1 2 102 2 1 Bob Canada
2 3 103 1 3 Charlie UK
3 4 104 3 1 NaN NaN
4 5 105 2 2 NaN NaN
Left join zahrnuje všechny objednávky z `df_orders`. Zákazníci 104 a 105 mají objednávky, ale nemají zákaznické informace, takže sloupce `customer_name` a `country` jsou pro tyto objednávky `NaN`.
Right Join (Pravé spojení)
Right join vrací všechny řádky z pravého DataFrame a odpovídající řádky z levého DataFrame. Pokud řádek v pravém DataFrame nemá shodu v levém DataFrame, odpovídající sloupce z levého DataFrame budou obsahovat hodnoty `NaN`.
Příklad:
# Right Join
df_right = pd.merge(df_orders, df_customers, on='customer_id', how='right')
print(df_right)
Výstup:
order_id customer_id product_id quantity customer_name country
0 1.0 101 1.0 2.0 Alice USA
1 2.0 102 2.0 1.0 Bob Canada
2 3.0 103 1.0 3.0 Charlie UK
3 NaN 106 NaN NaN David Australia
Right join zahrnuje všechny zákazníky z `df_customers`. Zákazník 106 má zákaznické informace, ale nemá žádné objednávky, takže sloupce `order_id`, `product_id` a `quantity` jsou pro tohoto zákazníka `NaN`.
Spojování DataFrames pomocí `df.join()`
Metoda `df.join()` se primárně používá ke spojování DataFrames na základě jejich indexů. Lze ji také použít pro spojování podle sloupců, ale pro spojování na základě sloupců je obvykle pohodlnější použít `pd.merge()`.
Syntaxe
DataFrame.join(other, on=None, how='left', lsuffix='', rsuffix='', sort=False)
Parametry
- other: Druhý DataFrame ke spojení.
- on: Název sloupce pro spojení. Musí být předán, pokud se index nepoužívá jako spojovací klíč.
- how: Jak zpracovat operaci levé a pravé sady. Výchozí hodnota je 'left'.
- lsuffix: Přípona, která se použije z levého DataFrame k přepsání překrývajících se názvů sloupců.
- rsuffix: Přípona, která se použije z pravého DataFrame k přepsání překrývajících se názvů sloupců.
- sort: Seřadí výsledný DataFrame lexikograficky podle spojovacích klíčů. Výchozí hodnota je False.
Spojování na indexu
Při spojování na indexu se parametr `on` nepoužívá.
Příklad:
# DataFrame 1: Customer Orders with Customer ID as Index
df_orders_index = df_orders.set_index('customer_id')
# DataFrame 2: Customer Information with Customer ID as Index
df_customers_index = df_customers.set_index('customer_id')
# Join on Index (Left Join)
df_join_index = df_orders_index.join(df_customers_index, how='left')
print(df_join_index)
Výstup:
order_id product_id quantity customer_name country
customer_id
101 1 1 2 Alice USA
102 2 2 1 Bob Canada
103 3 1 3 Charlie UK
104 4 3 1 NaN NaN
105 5 2 2 NaN NaN
V tomto příkladu je metoda `join()` použita k provedení left join na indexu (`customer_id`). Výsledek je podobný left joinu pomocí `pd.merge()`, ale spojení je založeno na indexu spíše než na sloupci.
Spojování na sloupci
Pro spojení na sloupci pomocí `df.join()`, musíte specifikovat parametr `on`.
Příklad:
# Joining on a column
df_join_column = df_orders.join(df_customers.set_index('customer_id'), on='customer_id', how='left')
print(df_join_column)
Výstup:
order_id customer_id product_id quantity customer_name country
0 1 101 1 2 Alice USA
1 2 102 2 1 Bob Canada
2 3 103 1 3 Charlie UK
3 4 104 3 1 NaN NaN
4 5 105 2 2 NaN NaN
Tento příklad demonstruje spojení `df_orders` s `df_customers` pomocí sloupce `customer_id`. Všimněte si, že `customer_id` je nastaven jako index v `df_customers` před provedením spojení.
Zpracování překrývajících se sloupců
Při slučování nebo spojování DataFrames je běžné setkat se s překrývajícími se názvy sloupců (sloupce se stejným názvem v obou DataFrames). Pandas poskytuje parametr `suffixes` ve funkci `pd.merge()` a parametry `lsuffix` a `rsuffix` v metodě `df.join()` pro řešení těchto situací.
Použití `suffixes` ve funkci `pd.merge()`
Parametr `suffixes` vám umožňuje specifikovat přípony, které budou přidány k překrývajícím se názvům sloupců, aby se odlišily.
Příklad:
# DataFrame 1: Product Information
df_products1 = pd.DataFrame({
'product_id': [1, 2, 3],
'product_name': ['Product A', 'Product B', 'Product C'],
'price': [10, 20, 15]
})
# DataFrame 2: Product Information (with potentially updated prices)
df_products2 = pd.DataFrame({
'product_id': [1, 2, 4],
'product_name': ['Product A', 'Product B', 'Product D'],
'price': [12, 18, 25]
})
# Merge with suffixes
df_merged_suffixes = pd.merge(df_products1, df_products2, on='product_id', suffixes=('_old', '_new'))
print(df_merged_suffixes)
Výstup:
product_id product_name_old price_old product_name_new price_new
0 1 Product A 10 Product A 12
1 2 Product B 20 Product B 18
V tomto příkladu jsou sloupce `product_name` a `price` přítomny v obou DataFrames. Parametr `suffixes` přidává přípony `_old` a `_new` pro rozlišení sloupců z levého a pravého DataFrame.
Použití `lsuffix` a `rsuffix` v metodě `df.join()`
Parametry `lsuffix` a `rsuffix` poskytují podobnou funkcionalitu pro `df.join()`. `lsuffix` se připojuje k překrývajícím se sloupcům levého DataFrame a `rsuffix` k překrývajícím se sloupcům pravého DataFrame.
Příklad:
# Join with lsuffix and rsuffix
df_products1_index = df_products1.set_index('product_id')
df_products2_index = df_products2.set_index('product_id')
df_joined_suffixes = df_products1_index.join(df_products2_index, lsuffix='_old', rsuffix='_new', how='outer')
print(df_joined_suffixes)
Výstup:
product_name_old price_old product_name_new price_new
product_id
1 Product A 10.0 Product A 12.0
2 Product B 20.0 Product B 18.0
3 Product C 15.0 NaN NaN
4 NaN NaN Product D 25.0
Praktické příklady a případy použití
Slučování a spojování DataFrames se široce používá v různých scénářích analýzy dat. Zde jsou některé praktické příklady:
Kombinování prodejních dat s informacemi o produktech
Běžným případem použití je kombinování prodejních dat s informacemi o produktech. Předpokládejme, že máte DataFrame obsahující prodejní transakce a další DataFrame obsahující podrobnosti o produktech. Tyto DataFrames můžete sloučit, abyste obohatili prodejní data o informace o produktech.
Příklad:
# Sales Transactions Data
df_sales = pd.DataFrame({
'transaction_id': [1, 2, 3, 4, 5],
'product_id': [101, 102, 103, 101, 104],
'quantity': [2, 1, 3, 1, 2],
'sales_date': ['2023-01-15', '2023-02-20', '2023-03-10', '2023-04-05', '2023-05-01']
})
# Product Information Data
df_products = pd.DataFrame({
'product_id': [101, 102, 103, 104],
'product_name': ['Laptop', 'Mouse', 'Keyboard', 'Monitor'],
'category': ['Electronics', 'Electronics', 'Electronics', 'Electronics'],
'price': [1200, 25, 75, 300]
})
# Merge Sales Data with Product Information
df_sales_enriched = pd.merge(df_sales, df_products, on='product_id', how='left')
print(df_sales_enriched)
Výstup:
transaction_id product_id quantity sales_date product_name category price
0 1 101 2 2023-01-15 Laptop Electronics 1200
1 2 102 1 2023-02-20 Mouse Electronics 25
2 3 103 3 2023-03-10 Keyboard Electronics 75
3 4 101 1 2023-04-05 Laptop Electronics 1200
4 5 104 2 2023-05-01 Monitor Electronics 300
Výsledný DataFrame `df_sales_enriched` obsahuje prodejní transakce spolu s odpovídajícími informacemi o produktech, což umožňuje podrobnější analýzu prodejních trendů a výkonnosti produktů.
Kombinování zákaznických dat s demografickými informacemi
Dalším běžným případem použití je kombinování zákaznických dat s demografickými informacemi. To umožňuje analyzovat chování zákazníků na základě demografických faktorů.
Příklad:
# Customer Data
df_customers = pd.DataFrame({
'customer_id': [1, 2, 3, 4, 5],
'customer_name': ['Alice', 'Bob', 'Charlie', 'David', 'Eve'],
'city': ['New York', 'London', 'Tokyo', 'Sydney', 'Berlin']
})
# Demographic Information Data
df_demographics = pd.DataFrame({
'city': ['New York', 'London', 'Tokyo', 'Sydney', 'Berlin'],
'population': [8419000, 8982000, 13960000, 5312000, 3769000],
'average_income': [75000, 65000, 85000, 90000, 55000]
})
# Merge Customer Data with Demographic Information
df_customer_demographics = pd.merge(df_customers, df_demographics, on='city', how='left')
print(df_customer_demographics)
Výstup:
customer_id customer_name city population average_income
0 1 Alice New York 8419000 75000
1 2 Bob London 8982000 65000
2 3 Charlie Tokyo 13960000 85000
3 4 David Sydney 5312000 90000
4 5 Eve Berlin 3769000 55000
Výsledný DataFrame `df_customer_demographics` obsahuje zákaznická data spolu s demografickými informacemi pro jejich příslušná města, což umožňuje analýzu chování zákazníků na základě demografie města.
Analýza globálních dat dodavatelského řetězce
Slučování v Pandas je cenné pro analýzu globálních dat dodavatelského řetězce, kde jsou informace často rozloženy do více tabulek. Například propojení dat dodavatelů, informací o přepravě a údajů o prodeji může odhalit úzká místa a optimalizovat logistiku.
Příklad:
# Supplier Data
df_suppliers = pd.DataFrame({
'supplier_id': [1, 2, 3],
'supplier_name': ['GlobalTech', 'EuroParts', 'AsiaSource'],
'location': ['Taiwan', 'Germany', 'China']
})
# Shipping Data
df_shipments = pd.DataFrame({
'shipment_id': [101, 102, 103, 104],
'supplier_id': [1, 2, 3, 1],
'destination': ['USA', 'Canada', 'Australia', 'Japan'],
'shipment_date': ['2023-01-10', '2023-02-15', '2023-03-20', '2023-04-25']
})
# Merge Supplier and Shipment Data
df_supply_chain = pd.merge(df_shipments, df_suppliers, on='supplier_id', how='left')
print(df_supply_chain)
Výstup:
shipment_id supplier_id destination shipment_date supplier_name location
0 101 1 USA 2023-01-10 GlobalTech Taiwan
1 102 2 Canada 2023-02-15 EuroParts Germany
2 103 3 Australia 2023-03-20 AsiaSource China
3 104 1 Japan 2023-04-25 GlobalTech Taiwan
Pokročilé techniky slučování
Slučování na více sloupcích
DataFrames můžete slučovat na základě více sloupců předáním seznamu názvů sloupců parametru `on`.
Příklad:
# DataFrame 1
df1 = pd.DataFrame({
'product_id': [1, 1, 2, 2],
'color': ['red', 'blue', 'red', 'blue'],
'quantity': [10, 15, 20, 25]
})
# DataFrame 2
df2 = pd.DataFrame({
'product_id': [1, 1, 2, 2],
'color': ['red', 'blue', 'red', 'blue'],
'price': [5, 7, 8, 10]
})
# Merge on multiple columns
df_merged_multiple = pd.merge(df1, df2, on=['product_id', 'color'], how='inner')
print(df_merged_multiple)
Výstup:
product_id color quantity price
0 1 red 10 5
1 1 blue 15 7
2 2 red 20 8
3 2 blue 25 10
Slučování s různými názvy sloupců
Pokud mají sloupce pro spojení různé názvy v obou DataFrames, můžete použít parametry `left_on` a `right_on` k určení názvů sloupců, které se mají použít pro slučování.
Příklad:
# DataFrame 1
df1 = pd.DataFrame({
'product_id': [1, 2, 3],
'product_name': ['Product A', 'Product B', 'Product C']
})
# DataFrame 2
df2 = pd.DataFrame({
'id': [1, 2, 4],
'price': [10, 20, 25]
})
# Merge with different column names
df_merged_different = pd.merge(df1, df2, left_on='product_id', right_on='id', how='left')
print(df_merged_different)
Výstup:
product_id product_name id price
0 1 Product A 1.0 10.0
1 2 Product B 2.0 20.0
2 3 Product C NaN NaN
Použití `indicator` pro analýzu sloučení
Parametr `indicator` ve funkci `pd.merge()` přidává do výsledného DataFrame sloupec s názvem `_merge`, který indikuje zdroj každého řádku. To je užitečné pro pochopení, které řádky se shodovaly a které ne.
Příklad:
# Merge with indicator
df_merged_indicator = pd.merge(df_orders, df_customers, on='customer_id', how='outer', indicator=True)
print(df_merged_indicator)
Výstup:
order_id customer_id product_id quantity customer_name country _merge
0 1.0 101 1.0 2.0 Alice USA both
1 2.0 102 2.0 1.0 Bob Canada both
2 3.0 103 1.0 3.0 Charlie UK both
3 4.0 104 3.0 1.0 NaN NaN left_only
4 5.0 105 2.0 2.0 NaN NaN left_only
5 NaN 106 NaN NaN David Australia right_only
Sloupec `_merge` indikuje, zda řádek pochází z obou DataFrames (`both`), pouze z levého DataFrame (`left_only`), nebo pouze z pravého DataFrame (`right_only`).
Validace typů sloučení
Parametr `validate` zajišťuje, že operace sloučení odpovídá očekávaným typům vztahů mezi DataFrames (např. 'one_to_one', 'one_to_many'). To pomáhá předcházet nekonzistencím a chybám v datech.
Příklad:
# Example with one-to-one validation
df_users = pd.DataFrame({
'user_id': [1, 2, 3],
'username': ['john_doe', 'jane_smith', 'peter_jones']
})
df_profiles = pd.DataFrame({
'user_id': [1, 2, 3],
'profile_description': ['Software Engineer', 'Data Scientist', 'Project Manager']
})
# Performing a one-to-one merge with validation
merged_df = pd.merge(df_users, df_profiles, on='user_id', validate='one_to_one')
print(merged_df)
Pokud sloučení poruší zadanou validaci (např. vztah typu many-to-one, když je zadáno 'one_to_one'), bude vyvolána chyba `MergeError`, která vás upozorní na potenciální problémy s integritou dat.
Úvahy o výkonu
Slučování a spojování DataFrames může být výpočetně náročné, zejména u velkých datových sad. Zde jsou tipy pro zlepšení výkonu:
- Použijte vhodný typ spojení: Výběr správného typu spojení může výrazně ovlivnit výkon. Například, pokud potřebujete pouze odpovídající řádky, použijte inner join.
- Indexujte sloupce pro spojení: Indexování sloupců pro spojení může urychlit proces slučování.
- Použijte vhodné datové typy: Zajistěte, aby sloupce pro spojení měly kompatibilní datové typy.
- Vyhněte se zbytečnému kopírování: Nastavte `copy=False` ve `pd.merge()` a `df.join()`, abyste se vyhnuli vytváření zbytečných kopií dat.
Závěr
Slučování a spojování DataFrames jsou základní operace v analýze dat. Pochopením různých typů spojení a technik můžete efektivně kombinovat a analyzovat data z různých zdrojů, odhalovat cenné poznatky a podporovat informované rozhodování. Od kombinování prodejních dat s informacemi o produktech po analýzu globálních dodavatelských řetězců, zvládnutí těchto technik vám umožní s jistotou se vypořádat se složitými úkoly manipulace s daty. Nezapomeňte zvážit dopady na výkon při práci s velkými datovými sadami a využít pokročilé funkce, jako jsou parametry `indicator` a `validate`, pro robustnější a komplexnější analýzu.